package it.polimi.swKnights.SWIMv2.ejb.helpRequest;

import it.polimi.swKnights.SWIMv2.ejb.authentication.LoginHandlerLocal;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.HelpRequest;
import it.polimi.swKnights.SWIMv2.ejb.entityBeans.RegisteredUser;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.InvalidLoginPrivilegesException;
import it.polimi.swKnights.SWIMv2.ejb.exceptions.LoginFailException;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.EntityNotFoundException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

/**
 * Session Bean implementation class SeeHelpRequest
 */
@Stateless
public class SeeHelpRequest implements SeeHelpRequestRemote
{

	@PersistenceContext(unitName = "swimv2-manager")
	private EntityManager manager; // manager handlin the persistence data

	@EJB
	private LoginHandlerLocal loginController;

	@Override
	public List<Map<String, String>> getHelpRequests(String username,
			String password) throws EntityNotFoundException,
			InvalidLoginPrivilegesException, LoginFailException
	{

		return this.getHelRequestsParameterized(username, password,
				"answeringUserName", false);
	}

	@Override
	public List<Map<String, String>> getHelRequests(String username,
			String password, String userNameHelped)
			throws EntityNotFoundException, InvalidLoginPrivilegesException,
			LoginFailException
	{

		return this.getHelRequestsParameterized(username, password,
				"askingUserName", false);

	}

	@Override
	public List<Map<String, String>> getAcceptedHelpRequests(String username,
			String password) throws EntityNotFoundException,
			InvalidLoginPrivilegesException, LoginFailException

	{
		return this.getHelRequestsParameterized(username, password,
				"askingUserName", true);
	}

	private List<Map<String, String>> getHelRequestsParameterized(
			String username, String password, String parameter,
			Boolean returnOnlyAccepted) throws EntityNotFoundException,
			InvalidLoginPrivilegesException, LoginFailException
	{
		checkSecurity(username, password, parameter);

		List<?> itemList = null;

		itemList = getQueryResult(username, parameter, returnOnlyAccepted); // helpRequestOfOfUserQuery.getResultList();

		List<HelpRequest> lstHelpRequest = new ArrayList<HelpRequest>();

		for (Object item : itemList)
		{
			HelpRequest help_req = (HelpRequest) item;
			lstHelpRequest.add(help_req);
		}

		return this.HelpRequestsToListMap(lstHelpRequest);
	}

	private List<?> getQueryResult(String username, String parameter,
			Boolean acceptedRequested)
	{

		String helpRequestOfUser;
		if (acceptedRequested == false)
		{

			helpRequestOfUser = "SELECT hr FROM HelpRequest AS hr "
					+ "WHERE hr." + parameter + "=:user "
					+ "AND hr.accepted=false "
					+ "AND hr.endDate >= current_date";
			
			Query helpRequestOfOfUserQuery = this.manager
					.createQuery(helpRequestOfUser);

			helpRequestOfOfUserQuery.setParameter("user", username);

			return helpRequestOfOfUserQuery.getResultList();
		}
		else
		{  
			
			
			helpRequestOfUser = "SELECT hr FROM HelpRequest AS hr "
					+ "WHERE hr." + parameter + "=:user "
					+ "AND hr.accepted=true "
					;
			
			Query helpRequestOfOfUserQuery = this.manager
					.createQuery(helpRequestOfUser);

			helpRequestOfOfUserQuery.setParameter("user", username);

			

			List<HelpRequest> acceptedReqs = new ArrayList<HelpRequest>(); 
			
			for(Object o: helpRequestOfOfUserQuery.getResultList())
			{
				if(o instanceof HelpRequest)
				{
					HelpRequest hr = (HelpRequest) o;
					
					Date toDay = new Date();
					Date end = hr.getEndDate();
					Date endPlus30 = new Date(end.getTime() + TimeUnit.DAYS.toMillis(30));
					
					
					if(toDay.before(endPlus30) && toDay.after(end))
					{
						acceptedReqs.add(hr);
					}
						
				}
			}
			
			return acceptedReqs;
		}

	}

	private List<Map<String, String>> HelpRequestsToListMap(
			List<HelpRequest> lstHelpRequest)

	{
		List<Map<String, String>> lstMapReqests = new ArrayList<Map<String, String>>();

		for (HelpRequest hr : lstHelpRequest)
		{

			Map<String, String> helpCard = new LinkedHashMap<String, String>();
			
			
			helpCard.put("asking", hr.getAskingUserName());
			helpCard.put("answering", hr.getAnsweringUserName());
			helpCard.put("creation_date",
					this.convertDate(hr.getCreationDate()));
			helpCard.put("id", hr.getId());
			helpCard.put("title", hr.getTitle());
			helpCard.put("summary", hr.getSummary());

			lstMapReqests.add(helpCard);

		}

		return lstMapReqests;
	}

	private void checkSecurity(String username, String password,
			String parameter) throws InvalidLoginPrivilegesException,
			LoginFailException
	{
		if (!parameter.equals("answeringUserName")
				&& !parameter.equals("askingUserName"))
		{
			throw new IllegalArgumentException(
					"maledetto ema, volevi fregarci, di nuovo ;) ;)");
		}
		this.loginController.checkLoginDataAndPrivileges(username, password,
				RegisteredUser.class);
	}

	private String convertDate(Date creationDate)
	{
		DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
		String strDate = df.format(creationDate);
		return strDate;
	}

}
